using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Windows;
using System.Windows.Interactivity;
using System.Windows.Media;
namespace Microsoft.Expression.Interactivity.Core
{
	public class DataStateBehavior : Behavior<FrameworkElement>
	{
		public static readonly DependencyProperty BindingProperty = DependencyProperty.Register("Binding", typeof(object), typeof(DataStateBehavior), new PropertyMetadata(new PropertyChangedCallback(DataStateBehavior.OnBindingChanged)));
		public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(object), typeof(DataStateBehavior), new PropertyMetadata(new PropertyChangedCallback(DataStateBehavior.OnValueChanged)));
		public static readonly DependencyProperty TrueStateProperty = DependencyProperty.Register("TrueState", typeof(string), typeof(DataStateBehavior), new PropertyMetadata(new PropertyChangedCallback(DataStateBehavior.OnTrueStateChanged)));
		public static readonly DependencyProperty FalseStateProperty = DependencyProperty.Register("FalseState", typeof(string), typeof(DataStateBehavior), new PropertyMetadata(new PropertyChangedCallback(DataStateBehavior.OnFalseStateChanged)));
		public object Binding
		{
			get
			{
				return base.GetValue(DataStateBehavior.BindingProperty);
			}
			set
			{
				base.SetValue(DataStateBehavior.BindingProperty, value);
			}
		}
		public object Value
		{
			get
			{
				return base.GetValue(DataStateBehavior.ValueProperty);
			}
			set
			{
				base.SetValue(DataStateBehavior.ValueProperty, value);
			}
		}
		public string TrueState
		{
			get
			{
				return (string)base.GetValue(DataStateBehavior.TrueStateProperty);
			}
			set
			{
				base.SetValue(DataStateBehavior.TrueStateProperty, value);
			}
		}
		public string FalseState
		{
			get
			{
				return (string)base.GetValue(DataStateBehavior.FalseStateProperty);
			}
			set
			{
				base.SetValue(DataStateBehavior.FalseStateProperty, value);
			}
		}
		private FrameworkElement TargetObject
		{
			get
			{
				return VisualStateUtilities.FindNearestStatefulControl(base.AssociatedObject);
			}
		}
		private IEnumerable<VisualState> TargetedVisualStates
		{
			get
			{
				List<VisualState> list = new List<VisualState>();
				if (this.TargetObject != null)
				{
					IList visualStateGroups = VisualStateUtilities.GetVisualStateGroups(this.TargetObject);
					IEnumerator enumerator = visualStateGroups.GetEnumerator();
					try
					{
						while (enumerator.MoveNext())
						{
							VisualStateGroup visualStateGroup = (VisualStateGroup)enumerator.get_Current();
							IEnumerator enumerator2 = visualStateGroup.get_States().GetEnumerator();
							try
							{
								while (enumerator2.MoveNext())
								{
									VisualState visualState = (VisualState)enumerator2.get_Current();
									list.Add(visualState);
								}
							}
							finally
							{
								IDisposable disposable = enumerator2 as IDisposable;
								if (disposable != null)
								{
									disposable.Dispose();
								}
							}
						}
					}
					finally
					{
						IDisposable disposable2 = enumerator as IDisposable;
						if (disposable2 != null)
						{
							disposable2.Dispose();
						}
					}
				}
				return list;
			}
		}
		protected override void OnAttached()
		{
			base.OnAttached();
			this.ValidateStateNamesDeferred();
		}
		private void ValidateStateNamesDeferred()
		{
			FrameworkElement frameworkElement = base.AssociatedObject.get_Parent() as FrameworkElement;
			if (frameworkElement != null && DataStateBehavior.IsElementLoaded(frameworkElement))
			{
				this.ValidateStateNames();
				return;
			}
			base.AssociatedObject.add_Loaded(delegate(object sender, RoutedEventArgs e)
			{
				this.ValidateStateNames();
			});
		}
		internal static bool IsElementLoaded(FrameworkElement element)
		{
			UIElement rootVisual = Application.get_Current().get_RootVisual();
			DependencyObject parent = element.get_Parent();
			if (parent == null)
			{
				parent = VisualTreeHelper.GetParent(element);
			}
			return parent != null || (rootVisual != null && element == rootVisual);
		}
		private void ValidateStateNames()
		{
			this.ValidateStateName(this.TrueState);
			this.ValidateStateName(this.FalseState);
		}
		private void ValidateStateName(string stateName)
		{
			if (base.AssociatedObject != null && !string.IsNullOrEmpty(stateName))
			{
				using (IEnumerator<VisualState> enumerator = this.TargetedVisualStates.GetEnumerator())
				{
					while (enumerator.MoveNext())
					{
						VisualState current = enumerator.get_Current();
						if (stateName == current.get_Name())
						{
							return;
						}
					}
				}
				throw new ArgumentException(string.Format(CultureInfo.get_CurrentCulture(), ExceptionStringTable.DataStateBehaviorStateNameNotFoundExceptionMessage, new object[]
				{
					stateName,
					(this.TargetObject != null) ? this.TargetObject.GetType().get_Name() : "null"
				}));
			}
		}
		private static void OnBindingChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
		{
			DataStateBehavior dataStateBehavior = (DataStateBehavior)obj;
			dataStateBehavior.Evaluate();
		}
		private static void OnValueChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
		{
			DataStateBehavior dataStateBehavior = (DataStateBehavior)obj;
			dataStateBehavior.Evaluate();
		}
		private static void OnTrueStateChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
		{
			DataStateBehavior dataStateBehavior = (DataStateBehavior)obj;
			dataStateBehavior.ValidateStateName(dataStateBehavior.TrueState);
			dataStateBehavior.Evaluate();
		}
		private static void OnFalseStateChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
		{
			DataStateBehavior dataStateBehavior = (DataStateBehavior)obj;
			dataStateBehavior.ValidateStateName(dataStateBehavior.FalseState);
			dataStateBehavior.Evaluate();
		}
		private void Evaluate()
		{
			if (this.TargetObject != null)
			{
				string stateName;
				if (ComparisonLogic.EvaluateImpl(this.Binding, ComparisonConditionType.Equal, this.Value))
				{
					stateName = this.TrueState;
				}
				else
				{
					stateName = this.FalseState;
				}
				VisualStateUtilities.GoToState(this.TargetObject, stateName, true);
			}
		}
	}
}
